﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using ArticleWeb.Controllers;
using ArticleWeb.Models;
using System.Threading;
using System.Text;
using System.IO;

namespace ArticleWeb.Extensions
{
    public class ArticleProcess
    {
        static string filePath;
        static ArticleProcessInfo pInfo;
        static StreamWriter sw;
        static Thread thread;
        public static void Start()
        {
            filePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "info.json");
            if (thread == null)
            {
                try
                {
                    if (!System.IO.File.Exists(filePath))
                    {
                        pInfo = new ArticleProcessInfo() { CurrentCompleted = true };
                    }
                    else
                    {
                        pInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<ArticleProcessInfo>(System.IO.File.ReadAllText(filePath, Encoding.UTF8));
                    }
                }
                catch
                {
                }
                if (pInfo == null)
                {
                    pInfo = new ArticleProcessInfo() { CurrentCompleted = true };
                }
                thread = new Thread(ThreadMain);
                thread.IsBackground = true;
                thread.Start();
            }
        }

        public static bool IsProcessThreadRuning
        {
            get
            {
                return thread.ThreadState == ThreadState.Running;
            }
        }

        public static void ThreadMain()
        {
            while (true)
            {
                using (var db = new Models.ApplicationDbContext("DefaultConnection2"))
                {
                    db.Configuration.AutoDetectChangesEnabled = false;
                    db.Configuration.LazyLoadingEnabled = false;
                    db.Configuration.ProxyCreationEnabled = false;
                    Article article;
                    if (!pInfo.CurrentCompleted)
                    {
                        article = db.Articles.Find(pInfo.CurrentArticleID);
                        if (article == null || article.SimHash != null)
                        {
                            while ((article = db.Articles.FirstOrDefault(x => x.SimHash == null)) == null)//未入库的
                            {
                                Thread.Sleep(5000);
                            }
                        }
                    }
                    else
                    {
                        while ((article = db.Articles.FirstOrDefault(x => x.SimHash == null)) == null)//未入库的
                        {
                            Thread.Sleep(5000);
                        }
                    }
                    var simHash = SimHashAnalyser.GetSimHash(article.Content);
                    pInfo.CurrentArticleID = article.ID;
                    List<ArticleSimHash> list;
                    while ((list = db.Articles.Where(x => x.SimHash != null && x.ID > pInfo.ArtilceOffsetAll)
                        .Select(x => new ArticleSimHash
                        {
                            ID = x.ID,
                            SimHash = x.SimHash
                        }).OrderBy(x=>x.ID)
                    .ToList(1, 200)).Count > 0) //已入库的分页处理
                    {
                        foreach (var item in list)
                        {
                            var value = (int)(SimHashAnalyser.GetLikenessValue(item.SimHash.Value, simHash) * 100);
                            if (value > 70)
                            {
                                db.ArticleSimilarities.Add(new ArticleSimilarity
                                {
                                    CategoryID = article.CatagoryID,
                                    LAID = article.ID,
                                    RAID = item.ID,
                                    Value = value
                                });
                                db.ArticleSimilarities.Add(new ArticleSimilarity
                                {
                                    CategoryID = article.CatagoryID,
                                    LAID = item.ID,
                                    RAID = article.ID,
                                    Value = value
                                });
                            }
                        }
                        db.SaveChanges();

                        //keep offset for next loop
                        pInfo.ArtilceOffsetAll = list.Last().ID;
                        try
                        {
                            var infoJson = Newtonsoft.Json.JsonConvert.SerializeObject(pInfo);
                            System.IO.File.WriteAllText(filePath, infoJson, Encoding.UTF8);
                        }
                        catch { }
                    }
                    article.SimHash = simHash;
                    db.Entry(article).State = System.Data.Entity.EntityState.Modified;
                    db.SaveChanges();

                    try
                    {
                        //reset offset
                        pInfo.ArtilceOffsetAll = 0;
                        var json = Newtonsoft.Json.JsonConvert.SerializeObject(pInfo);
                        System.IO.File.WriteAllText(filePath, json, Encoding.UTF8);
                    }
                    catch
                    {

                    }
                }
            }
        }
        public class ArticleProcessInfo
        {
            /// <summary>
            /// 当前正在入库的文章ID
            /// </summary>
            public int CurrentArticleID { get; set; }

            public bool CurrentCompleted { get; set; }

            /// <summary>
            /// 要比对的目标文章的偏移地址（ID）
            /// </summary>
            public int ArtilceOffsetAll { get; set; }

        }
        public class ArticleSimHash
        {
            public int ID { get; set; }
            public int? SimHash { get; set; }
        }
    }
}